#include "MissingCP.hpp"

using namespace BFT::order::messages;

MissingCP::MissingCP(uint32_t _seqNo, boost::shared_ptr<BFT::messages::Digest> _cpDig, uint32_t _sendingReplica)
	: MacArrayMessage::MacArrayMessage(MISSING_CP, computeSize(), _sendingReplica, BFT::Parameters::getOrderCount())
{
	seqNo = _seqNo;
	cpDigest = _cpDig;
	
	int bytes_size;
	boost::shared_ptr<char> bytes = getBytes(bytes_size);
	
	int offset = getOffset();
	
	//write the sequence number
	*(uint32_t*)(bytes.get()+offset) = htonl(seqNo);
	offset = SEQUENCE_NUMBER_SIZE;
	
	//write the digest
	int digest_size = cpDigest.get()->getSize();
	boost::shared_ptr<char> digest_bytes = cpDigest.get()->getBytes();
	memcpy( (void*)(bytes.get()+offset) , (const void*)(digest_bytes.get()) , digest_size);
}

MissingCP::MissingCP(boost::shared_ptr<char> _bytes, int _bytes_size)
	: MacArrayMessage::MacArrayMessage(_bytes, _bytes_size)
{
	unsigned int offset = getOffset();
	
	//read the sequence number
	seqNo = ntohl(*(uint32_t*)(_bytes.get()+offset) );
	offset += SEQUENCE_NUMBER_SIZE;
	
	//read the Digest
	int digest_size = BFT::messages::Digest::size();
	boost::shared_ptr<char> temp_bytes ( (char*)malloc(digest_size), free );
	memcpy( (void*)(temp_bytes.get()) , (const void *)(_bytes.get()+offset) , digest_size);
	offset += digest_size;
	cpDigest = BFT::messages::Digest::fromBytes(temp_bytes, digest_size);
	
	if (offset != _bytes_size - getAuthenticationSize())
	{
		fprintf(stderr, "trying to build a MissingCP from invalid bytes\n");
		exit(107);
	}
}

uint32_t MissingCP::computeSize()
{
	return SEQUENCE_NUMBER_SIZE + BFT::messages::Digest::size();
}
